package zweixin

import (
	"encoding/json"
	"errors"
	"strings"

	"gitee.com/zevenfly/goutil/znet"
)

type AccessTokenResponse struct {
	AccessToken string `json:"access_token"`
	ExpiresIn   int    `json:"expires_in"`
}

type AccessTokenErrorResponse struct {
	Errcode int
	Errmsg  string
}

// 更新 token。
func ApiUpdateAccessToken(appID, appSecret string) (accessToken string, expiresIn int, err error) {
	url := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appID + "&secret=" + appSecret

	retJson, err := znet.HttpGet(url)
	if err != nil {
		return "", 0, err
	}

	if strings.Contains(retJson, "access_token") {
		atr := AccessTokenResponse{}
		err := json.Unmarshal([]byte(retJson), &atr)
		if err != nil {
			return "", 0, err
		}
		return atr.AccessToken, atr.ExpiresIn, nil
	} else {
		ater := AccessTokenErrorResponse{}
		err := json.Unmarshal([]byte(retJson), &ater)
		if err != nil {
			return "", 0, err
		}
		return "", 0, errors.New(ater.Errmsg)
	}
}

// 发送消息。
func ApiSendVarServer(accessToken, postJson string) (errcode int, err error) {
	url := "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + accessToken

	retJson, err := znet.HttpPost(url, postJson, "application/x-www-form-urlencoded")
	if retJson == "" {
		return -2, err
	}

	ater := AccessTokenErrorResponse{}
	err = json.Unmarshal([]byte(retJson), &ater)
	if err != nil {
		return -2, err
	}
	return ater.Errcode, errors.New(ater.Errmsg)
}

// 发送文本信息。
func ApiSendTextVarServer(accessToken, openId, text string) (errcode int, err error) {
	json :=
		"{" +
			"\"touser\":\"" + openId + "\"," +
			"\"msgtype\":\"text\"," +
			"\"text\":" +
			"{" +
			"\"content\":\"" + text + "\"" +
			"}" +
			"}"

	return ApiSendVarServer(accessToken, json)
}

// 根据 group_id 群发消息。
func ApiSendToAllByGroup(accessToken, postJson string) (errcode int, err error) {
	url := "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=" + accessToken

	retJson, err := znet.HttpPost(url, postJson, "application/x-www-form-urlencoded")
	if retJson == "" {
		return -2, err
	}

	ater := AccessTokenErrorResponse{}
	err = json.Unmarshal([]byte(retJson), &ater)
	if err != nil {
		return -2, err
	}
	return ater.Errcode, errors.New(ater.Errmsg)
}

// 群发文本消息。
func ApiSendTextToAll(accessToken, text string) (errcode int, err error) {
	json :=
		"{" +
			"\"filter\":{" +
			//"\"is_to_all\":false" +
			"\"group_id\":\"0\"" +
			"}," +
			"\"text\":{" +
			"\"content\":\"" + text + "\"" +
			"}," +
			"\"msgtype\":\"text\"" +
			"}"

	return ApiSendToAllByGroup(accessToken, json)
}

// 根据 open_id 列表群发消息。
func ApiSendToAllByOpenIDList(accessToken, postJson string) (errcode int, err error) {
	url := "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=" + accessToken

	retJson, err := znet.HttpPost(url, postJson, "application/x-www-form-urlencoded")
	if retJson == "" {
		return -2, err
	}

	ater := AccessTokenErrorResponse{}
	err = json.Unmarshal([]byte(retJson), &ater)
	if err != nil {
		return -2, err
	}
	return ater.Errcode, errors.New(ater.Errmsg)
}

// 通过预览接口发送消息。
func ApiSendVarPreview(accessToken, postJson string) (errcode int, err error) {
	url := "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=" + accessToken

	retJson, err := znet.HttpPost(url, postJson, "application/x-www-form-urlencoded")
	if retJson == "" {
		return -2, err
	}

	ater := AccessTokenErrorResponse{}
	err = json.Unmarshal([]byte(retJson), &ater)
	if err != nil {
		return -2, err
	}
	return ater.Errcode, errors.New(ater.Errmsg)
}

// 通过预览接口发送文件消息。
func ApiSendTextVarPreview(accessToken, openID, text string) (errcode int, err error) {
	json :=
		"{" +
			"\"touser\":\"" + openID + "\"," +
			"\"text\":{" +
			"\"content\":\"" + text + "\"" +
			"}," +
			"\"msgtype\":\"text\"" +
			"}"

	return ApiSendVarPreview(accessToken, json)
}

// 更新菜单。
func ApiUpdateMenu(accessToken, postJson string) (errcode int, err error) {
	url := "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + accessToken

	retJson, err := znet.HttpPost(url, postJson, "application/x-www-form-urlencoded")
	if retJson == "" {
		return -2, err
	}

	ater := AccessTokenErrorResponse{}
	err = json.Unmarshal([]byte(retJson), &ater)
	if err != nil {
		return -2, err
	}
	return ater.Errcode, errors.New(ater.Errmsg)
}

//以下为封装的接口
//=============================================================================================

// 主动发送消息。先尝试通过普通接口，再尝试通过预览接口。
func TrySendText(accessToken, openID, text string) (errcode int, err error) {
	errcode, err = ApiSendTextVarServer(accessToken, openID, text)
	if errcode != 0 {
		errcode, err = ApiSendTextVarPreview(accessToken, openID, text)
	}
	return
}
